package logic

import (
	"context"
	"strings"

	"mall/common/enumx"
	"mall/common/modelx"
	"mall/common/resultx"
	"mall/service/forum/model"
	"mall/service/forum/rpc/internal/svc"
	"mall/service/forum/rpc/types/forum"

	"github.com/zeromicro/go-zero/core/logx"
)

type FeedListLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewFeedListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *FeedListLogic {
	return &FeedListLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *FeedListLogic) FeedList(in *forum.FeedListReq) (*forum.FeedListResp, error) {
	logx.Infof("FeedListReq: %+v ", in)
	//

	if in.Preload == "" && in.EagerLoad == "" {
		return nil, resultx.StatusError(resultx.REUQEST_PARAM_ERROR, "")
	}

	preloadMap, eagerLoadMap := modelx.GetPreloadMap(in.Preload, in.EagerLoad)
	logx.Infof("preloadMap: %+v ", preloadMap)
	// preloadMap:
	logx.Infof("eagerLoadMap: %+v ", eagerLoadMap)
	// eagerLoadMap:

	forumFeedEntityName := model.RpcEntityNames.ForumFeed
	_, hasSettingMap := model.RpcEntityPreloadMap[forumFeedEntityName] // ForumFeed的关联字段
	if !hasSettingMap {
		return &forum.FeedListResp{}, nil
	}

	forumFeedRepositoryName := model.RepositoryNames.ForumFeed
	columnMap, hasColumnMap := model.RepositoryPreloadMap[forumFeedRepositoryName] // ForumFeed的数据库字段
	if !hasColumnMap {
		return &forum.FeedListResp{}, nil
	}

	// 解析 preload 的字段
	var selectCols []string
	if preloadFields, hasPreloadFields := preloadMap[forumFeedEntityName]; hasPreloadFields {
		selectColMap := make(map[string]string)
		for _, field := range preloadFields {
			if _, exist := selectColMap[field]; !exist {
				if column, hasColumn := columnMap[field]; hasColumn {
					selectColMap[field] = column
				} else {
					selectColMap[field] = ""
				}
			}
		}
		for _, column := range selectColMap {
			if column != "" {
				selectCols = append(selectCols, column)
			}
		}
	}

	var count int64
	var err error
	var feedList []*model.ForumFeed

	if in.FeedIds != "" { // 根据ID获取
		filterMap := make(map[string]map[string][]interface{})
		filterMap[model.ForumFeedColumns.ID] = map[string][]interface{}{
			"in": modelx.UniqueValues(strings.Split(in.FeedIds, ","), 64),
		}
		filterMap[model.ForumFeedColumns.Status] = map[string][]interface{}{
			"equalTo": []interface{}{enumx.ObjectStatusAproved},
		}

		feedList, _, err = l.svcCtx.ForumUser.GetFeeds(l.ctx, model.M{
			"orderBy": model.ForumFeedColumns.ID + " DESC",
		}, -1, filterMap)
		if err != nil {
			return nil, err
		}
	} else {
		filterMap := make(map[string]map[string][]interface{})
		filterMap[model.ForumFeedColumns.Status] = map[string][]interface{}{
			"equalTo": []interface{}{enumx.ObjectStatusAproved},
		}
		feedList, count, err = l.svcCtx.ForumUser.GetFeeds(l.ctx, model.M{
			"offset":  in.Offset,
			"limit":   in.Limit,
			"orderBy": model.ForumFeedColumns.Sticky + " DESC, " + model.ForumFeedColumns.ID + " DESC",
		}, 2, filterMap)
		if err != nil {
			return nil, err
		}
	}

	var feeds []*forum.FeedInfo
	if len(feedList) > 0 {
		for _, feed := range feedList {
			feeds = append(feeds, &forum.FeedInfo{
				Id:              int64(feed.ID),
				ForumId:         int64(feed.ForumID),
				TopicId:         int64(feed.TopicID),
				PostId:          int64(feed.PostID),
				AuthorId:        int64(feed.AuthorID),
				AuthorName:      feed.AuthorNickname,
				AuthorAvatar:    feed.AuthorAvatar,
				AuthorIp:        feed.AuthorIP,
				AuthorLevel:     int32(feed.AuthorRankID),
				AuthorAnonymous: int32(feed.AuthorAnonymous),
				Excerpt:         feed.Excerpt,
				MediaId:         int64(feed.ThumbnailID),
				MediaUrl:        feed.ThumbnailURL,
				Status:          int32(feed.Status),
				StickyScore:     int32(feed.Sticky) * enumx.BlogStickyTypeOffset,
				CreatedAt:       modelx.FormatTime(feed.CreatedAt, ""),
				UpdatedAt:       modelx.FormatTime(feed.UpdatedAt, ""),
				LikeCount:       int32(feed.LikeCount),
				ReplyCount:      int32(feed.ReplyCount),
			})
		}
	}

	var hasNextPage int32
	var hasPreviousPage int32
	if count > 1 {
		hasNextPage = 1
		count = count - 2
	}
	if count > 0 {
		hasPreviousPage = 1
	}
	return &forum.FeedListResp{
		PageSize:        int64(in.Limit),
		Data:            feeds,
		HasNextPage:     hasNextPage,
		HasPreviousPage: hasPreviousPage,
		Offset:          in.Offset,
	}, nil
}
